package com.hdphone.zljutils.impl;

import android.annotation.SuppressLint;
import android.text.TextUtils;

import com.hdphone.zljutils.inter.IDateUtil;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

import androidx.annotation.NonNull;

/**
 * @author sq
 * @date 2020/10/19
 * @describe
 */
public class DateUtilImpl implements IDateUtil {

    @Override
    public Calendar getCalendarInstance() {
        return Calendar.getInstance(Locale.getDefault());
    }

    @Override
    public String date2String(Date date) {
        return date2String(date, "yyyy-MM-dd HH:mm:ss");
    }

    @Override
    public String date2String(Date date, String format) {
        if (date == null) {
            date = getCurrentDate();
        }
        if (TextUtils.isEmpty(format)) {
            format = "yyyy-MM-dd";
        }
        return new SimpleDateFormat(format, Locale.getDefault()).format(date);
    }

    @Override
    public int getWeekend() {
        return getCalendarInstance().get(Calendar.DAY_OF_WEEK);
    }

    @Override
    public Date string2Date(String date) {
        return string2Date(date, "yyyy-MM-dd");
    }

    @Override
    public Date string2Date(String date, String format) {
        try {
            return new SimpleDateFormat(format, Locale.getDefault()).parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return getCurrentDate();
    }

    @Override
    public int daysBetween(String early, String late) {
        Date earlyDate;
        Date lateDate;
        DateFormat df = DateFormat.getDateInstance();
        try {
            earlyDate = df.parse(early);
            lateDate = df.parse(late);
        } catch (ParseException e) {
            e.printStackTrace();
            return 0;
        }
        Calendar calst = Calendar.getInstance();
        Calendar caled = Calendar.getInstance();
        calst.setTime(earlyDate);
        caled.setTime(lateDate);
        // 设置时间为0时
        calst.set(Calendar.HOUR_OF_DAY, 0);
        calst.set(Calendar.MINUTE, 0);
        calst.set(Calendar.SECOND, 0);
        caled.set(Calendar.HOUR_OF_DAY, 0);
        caled.set(Calendar.MINUTE, 0);
        caled.set(Calendar.SECOND, 0);
        // 得到两个日期相差的天数
        int days = ((int) (caled.getTime().getTime() / 1000) - (int) (calst
                .getTime().getTime() / 1000)) / 3600 / 24;

        return days;
    }

    @Override
    public int hoursBetween(String early, String late) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
        Date earlyDate;
        Date lateDate;
        try {
            earlyDate = df.parse(early);
            lateDate = df.parse(late);
        } catch (ParseException e) {
            e.printStackTrace();
            return 0;
        }
        Calendar calst = Calendar.getInstance();
        Calendar caled = Calendar.getInstance();
        calst.setTime(earlyDate);
        caled.setTime(lateDate);
        // 得到两个日期相差的天数
        int hours = ((int) (caled.getTime().getTime() / 1000) - (int) (calst
                .getTime().getTime() / 1000)) / 3600;

        return hours;
    }

    @Override
    public Date getCurrentDate() {
        return new Date();
    }

    @Override
    public String getCurrentDateString(String format) {
        return date2String(getCurrentDate(), format);
    }

    @Override
    public String getShortTime(String time) {
        String shortstring = null;
        long now = Calendar.getInstance().getTimeInMillis();
        Date date = string2Date(time);
        if (date == null)
            return shortstring;
        long deltime = (now - date.getTime()) / 1000;
        if (deltime > 30 * 24 * 60 * 60) {
            shortstring = time;
        } else if (deltime > 7 * 24 * 60 * 60 && deltime < 30 * 24 * 60 * 60) {
            shortstring = (int) (deltime / (24 * 60 * 60)) + "天前";
        } else if (deltime > 1 * 24 * 60 * 60 && deltime < 7 * 24 * 60 * 60) {
            shortstring = "周" + getWeekDay(date) + " " + dateToStrLong(date);
        } else if (deltime > 60 * 60 && deltime < 1 * 24 * 60 * 60) {
            shortstring = (int) (deltime / (60 * 60)) + "小时前" + " "
                    + dateToStrLong(date);
        } else if (deltime > 60) {
            shortstring = (int) (deltime / (60)) + "分前";
        } else if (deltime > 1) {
            shortstring = "刚刚";
        } else {
            shortstring = "刚刚";
        }
        return shortstring;
    }

    private int getWeekDay(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int week_of_year = c.get(Calendar.DAY_OF_WEEK);
        return week_of_year - 1;
    }

    @SuppressLint("SimpleDateFormat")
    private String dateToStrLong(Date dateDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("HH:mm");
        String dateString = formatter.format(dateDate);
        return dateString;
    }

    @Override
    public String twoDateDistance(Date startDate, Date endDate) {

        if (startDate == null || endDate == null) {
            return null;
        }
        long timeLong = endDate.getTime() - startDate.getTime();
        if (timeLong < 60 * 1000)
            return timeLong / 1000 + "秒前";
        else if (timeLong < 60 * 60 * 1000) {
            timeLong = timeLong / 1000 / 60;
            return timeLong + "分钟前";
        } else if (timeLong < 60 * 60 * 24 * 1000) {
            timeLong = timeLong / 60 / 60 / 1000;
            return timeLong + "小时前";
        } else if (timeLong < 60 * 60 * 24 * 1000 * 7) {
            timeLong = timeLong / 1000 / 60 / 60 / 24;
            return timeLong + "天前";
        } else if (timeLong < 60 * 60 * 24 * 1000 * 7 * 4) {
            timeLong = timeLong / 1000 / 60 / 60 / 24 / 7;
            return timeLong + "周前";
        } else {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            sdf.setTimeZone(TimeZone.getTimeZone("GMT+08:00"));
            return sdf.format(startDate);
        }
    }

    @Override
    public String countdownTransform(long ms) {
        int hour = (int) ((ms % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));

        int minute = (int) ((ms % (1000 * 60 * 60)) / (1000 * 60));
        int second = (int) ((ms % (1000 * 60)) / 1000);

        return hour + ":" + minute + ":" + second;
    }

    @Override
    public String distanceTodayOrYesterday(Date d1, Date d2) {
        Calendar c1 = getCalendarInstance();
        Calendar c2 = getCalendarInstance();
        c1.setTime(d1);
        c2.setTime(d2);
        int startYear = c1.get(Calendar.YEAR);
        int startMonth = c1.get(Calendar.MONTH) + 1;
        int startDate = c1.get(Calendar.DATE);
        int endYear = c2.get(Calendar.YEAR);
        int endMonth = c2.get(Calendar.MONTH) + 1;
        int endDate = c2.get(Calendar.DATE);
        if (startYear < endYear) {
            return "昨天";
        } else {
            if (startMonth < endMonth) {
                return "昨天";
            } else {
                if (startDate < endDate) {
                    return "昨天";
                }
            }
        }
        return "今天";
    }

    @Override
    public String getPeriodOfTime(Date date) {
        if (date != null) {
            Calendar c = getCalendarInstance();
            c.setTime(date);
            int hour = c.get(Calendar.HOUR_OF_DAY);
            if (hour < 6) {
                return "凌晨";
            } else if (hour >= 6 && hour < 8) {
                return "早上";
            } else if (hour >= 8 && hour < 11) {
                return "上午";
            } else if (hour >= 11 && hour < 13) {
                return "中午";
            } else if (hour >= 13 && hour < 18) {
                return "下午";
            } else {
                return "晚上";
            }
        }
        return "";
    }

    @Override
    public String getHourMinuteWithDate(Date date) {
        if (date != null) {
            Calendar c = getCalendarInstance();
            c.setTime(date);
            return appendString(
                    c.get(Calendar.HOUR_OF_DAY) < 10 ? "0" + c.get(Calendar.HOUR_OF_DAY) : c.get(Calendar.HOUR_OF_DAY),
                    ":", c.get(Calendar.MINUTE) < 10 ? "0" + c.get(Calendar.MINUTE) : c.get(Calendar.MINUTE));
        }
        return "";
    }

    /**
     * 字符串的附加
     *
     * @param args
     * @return 附加后的字符
     */
    private String appendString(Object... args) {
        if (args == null || args.length < 1) {
            return "";
        }
        StringBuffer sb = new StringBuffer();

        sb.setLength(0);
        for (Object arg : args) {
            sb.append(arg);
        }
        return sb.toString();
    }

    @Override
    public boolean isToday(long time) {
        //当前时间
        Date now = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyyMMdd", Locale.getDefault());
        //获取今天的日期
        String nowDay = sf.format(now);


        //对比的时间
        String day = sf.format(new Date(time));
        return day.equals(nowDay);
    }

    @Override
    public String changeTimeToM(int time) {
        StringBuilder sb = new StringBuilder();
        int hour = 0;
        int minute = 0;
        int second = 0;
        if (time <= 0)
            return "00:00";
        else {
            minute = time / 1000;
            if (minute < 60) {
                second = time % 1000;
                sb.append(unitFormat(minute))
                        .append(":")
                        .append(unitFormat(second / 10));
            } else {
                hour = minute / 60;
                if (hour > 99)
                    return "99:59:59";
                minute = minute % 60;
                second = time - hour * 60000 - minute * 1000;
                sb.append(unitFormat(hour))
                        .append(":")
                        .append(unitFormat(minute))
                        .append(".")
                        .append(unitFormat(second / 10));
            }
        }
        return sb.toString();
    }

    @Override
    public String changeTime(int time) {
        StringBuilder sb = new StringBuilder();
        int hour = 0;
        int minute = 0;
        int second = 0;
        if (time <= 0)
            return "00:00";
        else {
            minute = time / 60;
            if (minute < 60) {
                second = time % 60;
                sb.append(unitFormat(minute))
                        .append(":")
                        .append(unitFormat(second));
            } else {
                hour = minute / 60;
                if (hour > 99)
                    return "99:59:59";
                minute = minute % 60;
                second = time - hour * 3600 - minute * 60;
                sb.append(unitFormat(hour))
                        .append(":")
                        .append(unitFormat(minute))
                        .append(":")
                        .append(unitFormat(second));
            }
        }
        return sb.toString();
    }

    @Override
    public String unitFormat(int i) {
        String retStr;
        if (i >= 0 && i < 10) {
            retStr = "0" + i;
        } else {
            retStr = "" + i;
        }
        return retStr;
    }

    @Override
    public Date getNowDate() {
        return new Date();
    }

    @Override
    public String getNowString() {
        return millis2String(System.currentTimeMillis(), getDefaultFormat());
    }

    @Override
    public String millis2String(long millis) {
        return millis2String(millis, getDefaultFormat());
    }

    @Override
    public String millis2String(long millis, @NonNull String format) {
        return millis2String(millis, new SimpleDateFormat(format, Locale.CHINA));
    }

    @Override
    public String millis2String(long millis, @NonNull DateFormat format) {
        return format.format(new Date(millis));
    }

    private static final ThreadLocal<SimpleDateFormat> SDF_THREAD_LOCAL = new ThreadLocal<>();


    private static SimpleDateFormat getDefaultFormat() {
        SimpleDateFormat simpleDateFormat = SDF_THREAD_LOCAL.get();
        if (simpleDateFormat == null) {
            simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
            SDF_THREAD_LOCAL.set(simpleDateFormat);
        }
        return simpleDateFormat;
    }
}
